<template>
  <el-dialog title="设置权限" custom-class="powerDialog" v-model="show" width="800px" :append-to-body="true"
             :close-on-press-escape="false" :close-on-click-modal="false">
    <div v-loading="loading">
      <el-tabs v-model="tabKey">
        <el-tab-pane label="页面配置" name="page"></el-tab-pane>
        <el-tab-pane label="菜单配置" name="menu"></el-tab-pane>
        <el-tab-pane label="其他配置" name="other"></el-tab-pane>
      </el-tabs>
      <div class="powerList" v-show="tabKey === 'menu'">
        <el-tree
            :data="menuList"
            node-key="id"
            ref="tree"
            default-expand-all
            :props="defaultProps">
          <template #default="{ data }">
            <div class="menuLi">
              <div class="menuLi_check" :class="data.checked?'is-checked el-icon-check':''"
                   v-on:click="clickMenuItem($event, !data.checked, data)">
              </div>
              <div class="menuLi_name">{{ data.name }}</div>
            </div>
          </template>
        </el-tree>
      </div>
      <div class="powerList" v-show="tabKey === 'page'">
        <div class="pageHeader">
          <div class="pageHeader_check">
            <el-checkbox v-model="selectAll" v-on:change="toggleSelectAll">全选</el-checkbox>
          </div>
          <div class="pageHeader_open" v-on:click="toggleOpen">
            <span v-if="!openAll">全部展开</span>
            <span v-else>全部关闭</span>
          </div>
        </div>
        <div class="pageSpan" v-for="item in pageList" v-bind:key="item">
          <div class="pageSpan_top">
            <div class="pageSpan_top_check">
              <el-checkbox v-model="item.checked" :indeterminate="item.indeterminate" @change="clickPageChecked($event, item)"></el-checkbox>
            </div>
            <div class="pageSpan_top_label" v-on:click="item.open = !item.open">{{ item.name }}</div>
            <div class="pageSpan_top_link" v-if="false">设置数据过滤</div>
            <div class="pageSpan_top_arrow el-icon-caret-bottom" v-on:click="item.open = !item.open"></div>
          </div>
          <div class="pageSpan_role" v-if="item.open">
            <div class="pageSpan_role_span" v-for="child in item.childList" v-bind:key="child">
              <el-checkbox v-model="child.checked" @change="clickChildChecked($event, item, child)">
                <i class="vbl vbl-TmpSVG api" v-if="child.type === 'api'"></i>
                <i class="vbl vbl-fangwen show" v-if="child.type === 'show'"></i>
                <i class="vbl vbl-quanxian1 power" v-if="child.type === 'power'"></i>
                {{ child.label }}
              </el-checkbox>
            </div>
          </div>
        </div>
      </div>
      <div class="powerList" v-show="tabKey === 'other'">
        <div class="paramForm">
          <el-form ref="form" label-width="140px" size="small" label-position="left">
            <template  v-for="item in roleParamList" :model="roleParam" v-bind:key="item">
              <el-form-item :label="item.name">
                <el-input v-if="item.type === 'input'" placeholder="请输入内容"></el-input>
                <template v-else-if="item.type === 'select'">
                  <el-select placeholder="请选择内容">
                    <el-option v-for="p in item.params" v-bind:key="p.key" :label="p.label" :value="p.key"></el-option>
                  </el-select>
                </template>
                <template v-else-if="item.type === 'checkbox'">
                </template>
                <template v-else-if="item.type === 'radio'">
                  <el-radio-group v-model="roleParam[item.key]">
                    <el-radio v-for="p in item.params" v-bind:key="p.key" :label="p.key">{{p.label}}</el-radio>
                  </el-radio-group>
                </template>
                <template v-else-if="item.type === 'switch'"></template>
              </el-form-item>
            </template>
          </el-form>
        </div>
      </div>
      <div class="footer">
        <el-button size="small" type="primary" v-on:click="onConfirmEvent" v-loading="formLoading">确定</el-button>
        <el-button size="small" type="default" v-on:click="close()">取消</el-button>
      </div>
    </div>
  </el-dialog>
</template>

<script>

export default {
  mixins: [],
  components: {
  },
  data() {
    return {
      show: false,
      menuList: [],
      pageList: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      loading: true,
      tabKey: "page",
      openAll: false,
      selectAll: true,
      formLoading: false,
      roleId: null,
      roleParamList: [],
      roleParam: {}
    }
  },
  props: {},
  setup() {
  },
  mounted() {
  },
  methods: {
    /**
     * 打开对话框
     */
    async open(param = {}) {
      let self = this
      this.show = true
      this.roleId = param.id
      this.loading = true
      this.formLoading = false
      this.openAll = false
      this.selectAll = false
      this.tabKey = "page"

      this.$api.getEditablePower().then(res => {
        self.setSelectMenuIdList(res.menu.data, param.menuIdList || [])
        self.menuList = res.menu.data
        self.putPageList(res.page.data, res.api, param.pageIdList || [], param.apiIdList || [], param.pagePower)

        self.roleParamList = [
          {
            key: "roleType",
            type: "radio",
            name: "角色分类",
            params: [
              {
                key: "admin",
                label: "管理员"
              },
              {
                key: "baocai",
                label: "包材库管"
              },
              {
                key: "yuanliao",
                label: "原料库管"
              },
              {
                key: "ganshen",
                label: "干参库管"
              },
              {
                key: "yuangong",
                label: "员工"
              },
              {
                key: "chejian",
                label: "车间主任"
              }
            ]
          }
        ]
        self.roleParamList.forEach(p => {
          self.roleParam[p.key] = param.roleParam && param.roleParam[p.key] ? param.roleParam[p.key] : p.defaultVal
        })

        self.loading = false
      })
    },
    /**
     * 关闭对话框
     */
    close() {
      this.show = false
      this.menuList = []
      this.pageList = []
    },

    /**
     * 整理页面数据
     * @param pageData
     * @param apiData
     * @param pageIdList
     * @param apiIdList
     * @param powers
     */
    putPageList(pageData, apiData, pageIdList, apiIdList, powers) {
      let pageList = [];
      let apiList = JSON.parse(JSON.stringify(apiData));
      pageData.sort((a, b) => b.sort - a.sort);
      pageData.forEach(page => {
        let childList = [];
        if (!page.noPower) {
            childList.push({
                label: "访问页面",
                key: page.id,
                checked: pageIdList.indexOf(page.id) > -1,
                type: "show"
            });
        }
        if (page.powerKeys && page.powerKeys.length) {
          let powerPage = powers ? powers[page.id] : null
          page.powerKeys.forEach(power => {
            childList.push({
              label: power.label,
              key: power.key,
              checked: powerPage && powerPage.indexOf(power.key) > -1,
              type: "power"
            })
          })
        }
        apiData.forEach((api, index) => {
          if (api.pageRouterIdList.indexOf(page.id) > -1) {
            childList.push({
              label: api.name,
              key: api.id,
              checked: apiIdList.indexOf(api.id) > -1,
              type: "api"
            })
            apiList.splice(index, 1)
          }
        })
        page.childList = childList

        let hasCancel = childList.some(c => {
          return !c.checked
        })
        page.open = false
        page.checked = !hasCancel
        let hasChecked = childList.some(c => {
          return c.checked
        })
        page.indeterminate = hasCancel && hasChecked;
        if (page.childList.length) pageList.push(page);
      });

      // if (apiList.length > 0) {
      //   let childList = []
      //   apiList.forEach((api, index) => {
      //     childList.push({
      //       label: api.name,
      //       key: api.id,
      //       checked: false,
      //       type: "api"
      //     })
      //   })
      //   pageList.push({
      //     open: false,
      //     checked: false,
      //     childList: childList,
      //     name: "其他"
      //   })
      // }

      this.pageList = pageList
      this.handleSelectAll()
    },

    /**
     * 点击页面项选择
     * @param val
     * @param item
     */
    clickPageChecked(val, item) {
      item.childList.forEach(child => {
        child.checked = val
      })
      item.indeterminate = false;
      this.handleSelectAll()
    },

    /**
     * 点击页面子项
     * @param val
     * @param item
     * @param child
     */
    clickChildChecked(val, item) {
      let hasCancel = item.childList.some(t => {
        return !t.checked
      })
      item.checked = !hasCancel
      let hasChecked = item.childList.some(t => {
        return t.checked
      })
      item.indeterminate = hasCancel && hasChecked;
      this.handleSelectAll()
    },

    /**
     * 全部展开/全部关闭
     */
    toggleOpen() {
      let self = this
      this.pageList.forEach(item => {
        item.open = !self.openAll
      })
      self.openAll = !self.openAll
    },

    /**
     * 全选/取消全选
     * @param val
     */
    toggleSelectAll(val) {
      this.pageList.forEach(item => {
        item.checked = val
        item.childList.forEach(child => {
          child.checked = val
        })
        item.indeterminate = false;
      })
    },

    /**
     * 根据子项选中状况设置全选状态
     */
    handleSelectAll() {
      let hasCancel = this.pageList.some(item => {
        return !item.checked
      })
      this.selectAll = !hasCancel
    },
    clickMenuItem(e, val, item) {
      item.checked = val
      if (item.children) {
        item.children.forEach(child => {
          this.clickMenuItem(e, val, child)
        })
      }
      let parent = this.getMenuParentItem(this.menuList, null, item)
      if (parent && parent.children) {
        parent.checked = parent.children.some(item => {
          return item.checked
        })
      }
      e.stopPropagation()
    },
    getMenuParentItem(menuList, p, item) {
      let parent = null
      menuList.forEach(menu => {
        if (item.id === menu.id) {
          parent = p
        }
        if (!parent && menu.children) {
          parent = this.getMenuParentItem(menu.children, menu, item)
        }
      })
      return parent
    },
    setSelectMenuIdList(menuList, selectIdList) {
      menuList.forEach(menu => {
        menu.checked = selectIdList.indexOf(menu.id) > -1
        if (menu.children) {
          this.setSelectMenuIdList(menu.children, selectIdList)
        }
      })
    },
    getSelectMenuIdList(menuList, selectIdList) {
      menuList.forEach(menu => {
        if (menu.checked) {
          selectIdList.push(menu.id)
        }
        if (menu.children) {
          this.getSelectMenuIdList(menu.children, selectIdList)
        }
      })
    },

    /**
     * 保存事件
     */
    onConfirmEvent() {
      let self = this

      let apiIdList = []
      let pageIdList = []
      let pagePower = {}
      let menuIdList = []
      this.getSelectMenuIdList(this.menuList, menuIdList)
      let setParentId = function (parentItem) {
        if (parentItem.children && parentItem.children.length > 0) {
          parentItem.children.forEach(child => {
            if (menuIdList.indexOf(child.id) > -1 && menuIdList.indexOf(parentItem.id) < 0) {
              menuIdList.push(parentItem.id)
            }
            setParentId(child)
          })
        }
      }
      this.menuList.forEach(item => {
        setParentId(item)
      })

      this.pageList.forEach(page => {
        page.childList.forEach(child => {
          if (child.checked) {
            switch (child.type) {
              case "show":
                pageIdList.push(child.key)
                break
              case "api":
                apiIdList.push(child.key)
                break
              case "power":
                if (!pagePower[page.id]) pagePower[page.id] = []
                pagePower[page.id].push(child.key)
                break
            }
          }
        })
      })

      self.formLoading = true
      self.$api.updateCharacterPower({
        apiIdList: apiIdList,
        pageIdList: pageIdList,
        menuIdList: menuIdList,
        pagePower: pagePower,
        roleParam: self.roleParam,
        id: self.roleId
      }).then(() => {
        self.formLoading = false
        self.close()
        self.$emit("reload")
      })
    }
  },
  watch: {}
}
</script>
<style scoped lang="scss">
.powerList{
  min-height: 100px;
}
.pageHeader {
  width: 100%;
  height: 40px;
  display: flex;
  align-items: center;

  .pageHeader_check {
    padding-left: 11px;
    flex: 1;
  }

  .pageHeader_open {
    font-size: 12px;
    color: var(--href);
    cursor: pointer;

    &:hover {
      text-decoration: underline;
    }
  }
}

.pageSpan {
  border: 1px solid var(--border-bd);
  border-radius: 5px;
  margin-bottom: 10px;
  cursor: pointer;

  &:last-child {
    margin-bottom: 0;
  }

  .pageSpan_top {
    height: 28px;
    padding: 0 10px;
    display: flex;
    line-height: 28px;
    align-items: center;
    font-size: 14px;
    background: var(--bg-page);
    border-radius: 5px 5px 0 0;

    .pageSpan_top_arrow {
      color: var(--font-hd);
      height: 100%;
      line-height: 28px;
    }

    .pageSpan_top_check {
      margin-right: 5px;
    }

    .pageSpan_top_label {
      flex: 1;
      height: 100%;
      font-weight: bold;
    }

    .pageSpan_top_link {
      color: var(--href);
      cursor: pointer;

      &:hover {
        text-decoration: underline;
      }
    }
  }

  .pageSpan_role {
    display: flex;
    flex-flow: wrap row;
    padding: 5px 10px;

    .pageSpan_role_span {
      width: 20%;
      padding: 5px 0;
      display: flex;
      align-items: center;

      :deep(.el-checkbox__label) {
        font-size: 12px;
      }

      i {
        font-size: 14px;

        &.api {
          color: var(--success);
        }

        &.show {
          color: var(--warning);
        }

        &.power {
          color: var(--danger);
        }
      }
    }
  }

  :deep(.el-checkbox__input.is-indeterminate) .el-checkbox__inner {
    background-color: #e6a23c !important;
    border-color: #e6a23c !important;
  }
}

.menuLi {
  width: 100%;
  display: flex;
  align-items: center;

  .menuLi_check {
    display: inline-block;
    position: relative;
    border: 1px solid #dcdfe6;
    border-radius: 2px;
    box-sizing: border-box;
    width: 14px;
    height: 14px;
    background-color: #fff;
    z-index: 1;
    transition: border-color .25s cubic-bezier(.71, -.46, .29, 1.46), background-color .25s cubic-bezier(.71, -.46, .29, 1.46);
    line-height: 14px;
    text-align: center;

    &.is-checked {
      background-color: var(--primary);
      border-color: var(--primary);
      color: #fff;
      font-size: 12px;
    }
  }

  .menuLi_name {
    margin-left: 10px;
  }
}
</style>
